/*
  封装axios函数：

    1. 成功就是成功，失败就是失败（请求失败、功能失败）
    2. 成功得到成功的数据，失败自动提示失败原因
    3. 复用请求地址 /api, 添加公共请求参数
    4. 失败提示的错误信息更准确
    5. 请求添加进度条提示
*/

import axios from "axios";
import NProgress from "nprogress";
import "nprogress/nprogress.css";

NProgress.configure({ showSpinner: false });

// 返回axios的“实例”
const request = axios.create({
  baseURL: "/mock", // 请求基础路径（将来使用request发送请求，自动在请求地址前面添加baseURL）
  headers: {}, // 公共请求头
  timeout: 20000, // 请求超时时间（请求超过时间还未响应，就会自动中断请求报错）
});

/*
  const res = await request({ method: 'Get', url: '/xxx' });

  但我们使用request函数去发送请求的时候，整体触发流程
    1. request({ method: 'Get', url: '/xxx' })
    2. 触发请求拦截器（成功的回调）
    3. 内部发送请求
    4. 等响应结果回来，触发响应拦截器
      当响应状态码2xx，触发成功的回调（请求成功）
      当响应状态码非2xx，触发失败的回调（请求失败）
    5. 此时request函数执行完了，最后触发await后面的内容

      return Promise.resolve(config)
        .then(请求拦截器成功, 请求拦截器失败)
        .then(发送请求函数，undefined)
        .then(响应拦截器成功, 响应拦截器失败)
*/

const errMessages = {
  401: "未授权",
  403: "禁止访问",
  404: "资源找不到",
  407: "登录过期",
  500: "服务器错误",
};

// 请求拦截器
request.interceptors.request.use(
  // 成功的回调
  (config) => {
    // config 是发送请求的配置项
    // 作用：用来添加公共请求参数
    // config.headers.token = 'xxxx';

    // 开始进度条
    NProgress.start();

    // 必须返回配置项
    return config;
  }
  // 失败的回调
  // () => {}
);

// 响应拦截器
request.interceptors.response.use(
  // 成功的回调 --> 请求成功
  (response) => {
    // 结束进度条
    NProgress.done();
    /*
      response 响应对象
        headers
        config
        request
        data 成功的数据
        status
    */
    if (response.data.code === 200) {
      // 功能成功
      return response.data.data;
    } else {
      // 功能失败
      alert(response.data.message);
      return Promise.reject(response.data.message);
    }
  },
  // 失败的回调 --> 请求失败
  (error) => {
    // 结束进度条
    NProgress.done();
    /*
      请求失败
        error.message 失败原因
          请求超时：timeout of 10ms exceeded
          断网了：Network Error
        error.response.status 响应状态码

        error.response 有值，说明服务器有响应，响应结果是失败的
        error.response 没有值，说明请求在客户端就中断了（服务器没有返回响应），结果失败
    */
    let message = "未知错误，请联系客服解决";
    if (error.response) {
      // if (error.response.status === 404) {
      //   alert("访问资源不存在");
      // } else if (error.response.status === 500) {
      //   alert("服务器错误，请联系管理员解决");
      // }
      // alert(errMessages[error.response.status] || "未知错误，请联系客服解决");
      if (errMessages[error.response.status]) {
        message = errMessages[error.response.status];
      }
    } else {
      if (error.message.indexOf("timeout") > -1) {
        // 请求超时
        // alert("当前网络环境不稳定，请切换4/5G网络或WIFI网络试试");
        message = "当前网络环境不稳定，请切换4/5G网络或WIFI网络试试";
      } else if (error.message.indexOf("Network") > -1) {
        // 断网了
        // alert("没有检测到网络，请打开网络链接试试");
        message = "没有检测到网络，请打开网络链接试试";
      }
    }
    alert(message);
    return Promise.reject(message);
  }
);

export default request;
